package com.zsr.example.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zsr.example.config.exception.CommonJsonException;
import com.zsr.example.entity.UcenterMember;
import com.zsr.example.mapper.UcenterMemberMapper;
import com.zsr.example.service.RedisService;
import com.zsr.example.service.UcenterMemberService;
import com.zsr.example.util.JwtUtil;
import com.zsr.example.util.MD5;
import com.zsr.example.util.ValidatorUtil;
import com.zsr.example.util.constants.RedisKeyConstants;
import com.zsr.example.vo.MemberReq;
import com.zsr.example.vo.front.LoginVo;
import com.zsr.example.vo.front.RegisterVo;
import com.zsr.example.vo.front.UserInfoVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Arrays;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 会员表 服务实现类
 * </p>
 *
 * @author zsr
 * @since 2021-12-04
 */
@Service
public class UcenterMemberServiceImpl extends ServiceImpl<UcenterMemberMapper, UcenterMember> implements UcenterMemberService {
    /*@Autowired
    private RedisTemplate<String, String> redisTemplate;*/

    @Autowired
    private RedisService redisService;

    private String[] sysKeyType = {"mobile", "email"};

    @Override
    public String login(LoginVo loginVo) {
        String mobile = loginVo.getMobile();
        String password = loginVo.getPassword();
        String email = loginVo.getEmail();
        String regType = loginVo.getRegType();

        //安全校验

        if (!Arrays.asList(sysKeyType).contains(regType)) throw new CommonJsonException("20001", "非法篡改数据");
        boolean isMobile = regType.equals("mobile");
        //登录类型的值 手机号 或者邮箱
        String regTypeValue = isMobile ? mobile : email;

        //校验参数
        if (isMobile && StringUtils.isEmpty(mobile)) throw new CommonJsonException("20001", "请输入手机号");
        if (!isMobile && StringUtils.isEmpty(email)) throw new CommonJsonException("20001", "请输入邮箱");
        if (StringUtils.isEmpty(password)) throw new CommonJsonException("20001", "请输入密码");


        //获取会员
        UcenterMember member = baseMapper.selectOne(new QueryWrapper<UcenterMember>().eq(regType, regTypeValue));
        if (null == member)  throw new CommonJsonException("20001", "用户不存在");

        //校验密码
        if (!MD5.encrypt(password).equals(member.getPassword()))  throw new CommonJsonException("20001", "密码错误");

        //校验是否被禁用
        if (member.getIsDisabled())  throw new CommonJsonException("20001", "用户被冻结："+member.getDisableReason());

        //统计登录人数
        redisService.hyperLogAdd(RedisKeyConstants.LOGIN_NUM_TODAY_KEY,member.getId());
        redisService.hyperLogUnion(RedisKeyConstants.LOGIN_NUM_ALL_KEY, RedisKeyConstants.LOGIN_NUM_TODAY_KEY);

        //使用JWT生成token字符串
        String token = JwtUtil.getJwtToken(member.getId(), member.getNickname());
        //token 存入redis
        redisService.opsForValueSet(RedisKeyConstants.SSO_LOGIN_KEY+member.getId(), token, 30L, TimeUnit.DAYS);

        member.setLastLoginTime(new Date());
        this.updateById(member);
        return token;
    }

    /**
     * 会员注册
     *
     * @param registerVo
     */
    @Override
    public void register(RegisterVo registerVo) {
        //获取注册信息，进行校验
        String nickname = registerVo.getNickname();
        String mobile = registerVo.getMobile();
        String email = registerVo.getEmail();
        String regType = registerVo.getRegType();
        String password = registerVo.getPassword();
        String pwd2 = registerVo.getPwd2();
        String code = registerVo.getCode();

        //安全校验
        if (!Arrays.asList(sysKeyType).contains(regType)) throw new CommonJsonException("20001", "非法篡改数据");

        boolean isMobile = regType.equals("mobile");
        //注册类型的值 手机号 或者邮箱
        String regTypeValue = isMobile ? mobile : email;
        //校验参数
        if (isMobile && StringUtils.isEmpty(mobile)) throw new CommonJsonException("20001", "请输入手机号");
        if (!isMobile && StringUtils.isEmpty(email)) throw new CommonJsonException("20001", "请输入邮箱");
        if (StringUtils.isEmpty(code)) throw new CommonJsonException("20001", "请输入验证码");
        if (StringUtils.isEmpty(password)) throw new CommonJsonException("20001", "请输入密码");
        if (StringUtils.isEmpty(pwd2)) throw new CommonJsonException("20001", "请输入确认密码");
        if (!password.equals(pwd2)) throw new CommonJsonException("20001", "确认密码不一致");

        //校验校验验证码
        //从redis获取发送的验证码
        String mobleCode = redisService.opsForValueGet(regTypeValue);
        if (!code.equals(mobleCode)) throw new CommonJsonException("20001", "验证码错误");

        //查询数据库中是否存在相同的手机号码 or 邮箱
        Integer count = baseMapper.selectCount(new QueryWrapper<UcenterMember>().eq(regType, regTypeValue));
        if (count > 0) throw new CommonJsonException("20001", isMobile ? "该手机号已注册" : "该邮箱已注册");

        //字段校验
        if(!ValidatorUtil.isNickName(nickname)) throw new CommonJsonException("20001", "昵称长度为2-10个字符");
        if(!ValidatorUtil.isEmail(email)) throw new CommonJsonException("20001", "请输入正确格式的邮箱");

        //添加注册信息到数据库
        UcenterMember member = new UcenterMember();
        member.setNickname(nickname);
        member.setMobile(registerVo.getMobile());
        member.setEmail(registerVo.getEmail());
        member.setPassword(MD5.encrypt(password));
        member.setIsDisabled(false);
        member.setAvatar("https://wisdom-education-single.oss-cn-shenzhen.aliyuncs.com/avatar/member-default.png");
        this.save(member);
    }

    @Override
    public UserInfoVo getLoginInfo(String memberId) {
        UcenterMember member = baseMapper.selectById(memberId);
        UserInfoVo userInfoVo = new UserInfoVo();
        BeanUtils.copyProperties(member, userInfoVo);
        return userInfoVo;
    }

     /**
     * 根据微信openId查询用户
     * @param openid 微信openId
     * @return
     */
    @Override
    public UcenterMember getByOpenid(String openid) {
        QueryWrapper<UcenterMember> wrapper=new QueryWrapper<>();
        wrapper.eq("openid",openid);
        UcenterMember member = this.getOne(wrapper);
        return member;
    }

    @Override
    public Integer countRegisterByDay(String day) {
        return baseMapper.selectRegisterCount(day);
    }

    @Override
    public void pageQuery(Page<UcenterMember> page, MemberReq memberReq) {
        //MP 构建条件
        QueryWrapper<UcenterMember> wrapper = new QueryWrapper<>();
        String email = memberReq.getEmail();
        String mobile = memberReq.getMobile();
        String nickname = memberReq.getNickname();
        String begin = memberReq.getBegin();
        String end = memberReq.getEnd();
        if (!StringUtils.isEmpty(email)) wrapper.like("email", email);
        if (!StringUtils.isEmpty(mobile)) wrapper.like("mobile", mobile);
        if (!StringUtils.isEmpty(nickname)) wrapper.like("nickname", nickname);
        if (!StringUtils.isEmpty(begin)) wrapper.ge("gmt_create", begin);//大于
        if (!StringUtils.isEmpty(end)) wrapper.le("gmt_modified", end);//小于
        baseMapper.selectPage(page, wrapper);
    }
}
